package coreGinServer

import (
	"context"
	"errors"
	"fmt"
	"io"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gitee.com/xgh2012/api-core/coreMiddleware"
	"gitee.com/xgh2012/api-core/coreZapLog"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// StartSever 启动服务
func StartSever(port int, name string, registerFunc func(engine *gin.Engine)) (*gin.Engine, *http.Server) {
	//禁用 gin 默认日志
	gin.DefaultWriter = io.Discard
	gin.DefaultErrorWriter = io.Discard

	gin.SetMode(gin.ReleaseMode) // 使用生产模式
	engine := gin.New()          // 使用 gin.New() 而不是 gin.Default()

	// 使用中间件
	engine.Use(gin.Recovery())
	engine.Use(coreMiddleware.SchemeDetector())
	engine.Use(coreMiddleware.TraceMiddleware())

	// 注册路由
	registerFunc(engine)

	// 启动HTTP服务器
	srv := &http.Server{
		Addr:              fmt.Sprintf(":%d", port),
		Handler:           engine,
		ReadTimeout:       30 * time.Second,  // 增加读取超时时间
		WriteTimeout:      30 * time.Second,  // 增加写入超时时间
		IdleTimeout:       120 * time.Second, // 增加空闲超时时间
		ReadHeaderTimeout: 10 * time.Second,  // 添加读取头部超时
	}

	// 启动服务器
	go func() {
		coreZapLog.Logger.Info(name+"正在启动", zap.String("addr", srv.Addr))
		if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			coreZapLog.Logger.Error(name+"监听失败", zap.Error(err))
			os.Exit(1)
		}
	}()
	coreZapLog.Logger.Info(name+"启动成功", zap.String("addr", srv.Addr))

	return engine, srv
}

// StopServer 监听关闭服务
func StopServer(srv *http.Server, name string) {
	// 优雅关闭服务器
	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	coreZapLog.Logger.Info(name + " 正在关闭...")

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		coreZapLog.Logger.Error(name+"关闭失败，强制关闭", zap.Error(err))
		os.Exit(1)
	}

	coreZapLog.Logger.Info(name + "关闭成功")
}
